package entidades;

import util.Util;
import util.exceptions.NaoExisteBlocoASerTrocadoException;
import util.exceptions.NaoExistemPeersSuficientesParaSeFazerTroca;
import entidades.politica.PoliticaSelecaoBlocos;
import entidades.politica.PoliticaSelecaoBlocosMaisRaro;
import entidades.politica.PoliticaSelecaoVizinhos;

public class Peer extends Entidade {

	public final static double taxa = Util.MI;
	private boolean recomendado;
	private String assinatura;
	private PoliticaSelecaoVizinhos politicaSelecaoVizinhos;
	private PoliticaSelecaoBlocos politicaSelecaoBlocos;

	public Peer(double instanteChegada, PoliticaSelecaoVizinhos politicaSelecaoVizinhos, PoliticaSelecaoBlocos politicaSelecaoBlocos, boolean recomendado) {
		this(instanteChegada, politicaSelecaoVizinhos, politicaSelecaoBlocos);
		this.recomendado = recomendado;
	}
	
	public Peer(double instanteChegada, PoliticaSelecaoVizinhos politicaSelecaoVizinhos, PoliticaSelecaoBlocos politicaSelecaoBlocos ) {
		super(instanteChegada);
		this.assinatura = Util.criarAssinatura();
		this.politicaSelecaoVizinhos = politicaSelecaoVizinhos;
		this.politicaSelecaoBlocos = politicaSelecaoBlocos;
		this.recomendado = false;
	}
	
	public boolean isRecomendado() {
		return recomendado;
	}

	public void setRecomendado(boolean recomendado) {
		this.recomendado = recomendado;
	}

	public String getAssinatura() {
		return assinatura;
	}

	public void setAssinatura(String assinatura) {
		this.assinatura = assinatura;
	}

	public Peer selecionaPeer() throws NaoExistemPeersSuficientesParaSeFazerTroca {
		return politicaSelecaoVizinhos.seleciona(this);
	}
	
	public int selecionaBloco(Peer peerDestino) throws NaoExisteBlocoASerTrocadoException {
		return politicaSelecaoBlocos.seleciona(this, peerDestino);
	}

	public void recebeBloco(int bloco) {
		if (politicaSelecaoBlocos instanceof PoliticaSelecaoBlocosMaisRaro) {
			((PoliticaSelecaoBlocosMaisRaro) politicaSelecaoBlocos).atualizaDisponibilidade(bloco);
		}
		
		char[] a = assinatura.toCharArray();
		a[bloco] = '1';
		setAssinatura(String.valueOf(a));
	}
	
	public boolean virouSeed() {
		return !assinatura.contains("0");
	}
}
